using Kopernikus.Collections.Generic;

namespace Kopernikus.Parsing.GrammarSets
{
    public class TerminalAndNonterminalSymbols
    {
        private readonly IGrammar m_grammar;
        private Set<Symbol> m_allSymbols;
        private Set<Symbol> m_nonTerminalSymbols;
        private Set<Symbol> m_terminalSymbols;

        public TerminalAndNonterminalSymbols(IGrammar grammar)
        {
            m_grammar = grammar;
        }

        public IGrammar Grammar
        {
            get { return m_grammar; }
        }

        public Set<Symbol> AllSymbols
        {
            get
            {
                Calculate();
                return m_allSymbols;
            }
        }

        public Set<Symbol> TerminalSymbols
        {
            get
            {
                Calculate();
                return m_terminalSymbols;
            }
        }

        public Set<Symbol> NonTerminalSymbols
        {
            get
            {
                Calculate();
                return m_nonTerminalSymbols;
            }
        }

        private void Calculate()
        {
            if (m_terminalSymbols != null)
            {
                return;
            }

            m_allSymbols = new Set<Symbol>();
            m_terminalSymbols = new Set<Symbol>();
            m_nonTerminalSymbols = new Set<Symbol>();

            foreach (Production p in Grammar.Productions)
            {
                m_nonTerminalSymbols.Add(p.LHS);
                m_terminalSymbols.Add(p.RHS);
            }
            m_terminalSymbols.Remove(m_nonTerminalSymbols);

            m_allSymbols.Add(m_terminalSymbols);
            m_allSymbols.Add(m_nonTerminalSymbols);
        }
    }
}